"""
垃圾检测算法服务
训练和集成垃圾检测专用模型，实现垃圾分类的智能识别功能
"""
import asyncio
import logging
import cv2
import numpy as np
from datetime import datetime, timedelta
from typing import List, Dict, Optional, Tuple, Any
from uuid import uuid4
import time
from collections import defaultdict, deque
import json

try:
    from ultralytics import YOLO
    import torch
    YOLO_AVAILABLE = True
except ImportError:
    YOLO_AVAILABLE = False
    logging.warning("YOLOv8 not available. Waste detection will use mock data.")

from schemas.hygiene_management import (
    WasteDetection, WasteAnalysisResult, WasteType, WasteDetectionConfig,
    HygieneIssue, HygieneIssueType
)
from core.config import get_settings
from services.campus_environment_hygiene.waste_model_manager import waste_model_manager

logger = logging.getLogger(__name__)
settings = get_settings()


class WasteDetectionModel:
    """垃圾检测模型封装"""
    
    def __init__(self, config: WasteDetectionConfig):
        self.config = config
        self.model = None
        self.device = None
        self.is_loaded = False
        
        # 垃圾类型映射（COCO类别到自定义类别）
        self.waste_type_mapping = {
            'bottle': WasteType.PLASTIC,
            'cup': WasteType.PLASTIC,
            'fork': WasteType.PLASTIC,
            'knife': WasteType.PLASTIC,
            'spoon': WasteType.PLASTIC,
            'bowl': WasteType.PLASTIC,
            'banana': WasteType.ORGANIC,
            'apple': WasteType.ORGANIC,
            'orange': WasteType.ORGANIC,
            'broccoli': WasteType.ORGANIC,
            'carrot': WasteType.ORGANIC,
            'book': WasteType.PAPER,
            'laptop': WasteType.ELECTRONIC,
            'mouse': WasteType.ELECTRONIC,
            'keyboard': WasteType.ELECTRONIC,
            'cell phone': WasteType.ELECTRONIC,
            'wine glass': WasteType.GLASS,
            'scissors': WasteType.METAL,
        }
        
        # 性能统计
        self.stats = {
            'total_detections': 0,
            'successful_detections': 0,
            'failed_detections': 0,
            'average_processing_time': 0.0,
            'waste_type_counts': defaultdict(int)
        }
    
    async def load_model(self):
        """加载模型"""
        try:
            if not YOLO_AVAILABLE:
                logger.warning("YOLOv8 not available, using mock model")
                self.is_loaded = True
                return
            
            # 设置设备
            if torch.cuda.is_available():
                self.device = torch.device('cuda')
            else:
                self.device = torch.device('cpu')
            
            # 加载YOLOv8模型
            if self.config.model_type == "yolov8":
                # 使用预训练的COCO模型，可以检测一些垃圾相关物品
                self.model = YOLO('yolov8n.pt')  # 可以替换为专门的垃圾检测模型
                if torch.cuda.is_available():
                    self.model.to(self.device)
            
            self.is_loaded = True
            logger.info(f"Waste detection model loaded on {self.device}")
            
        except Exception as e:
            logger.error(f"Failed to load waste detection model: {e}")
            self.is_loaded = False
            raise
    
    async def detect_waste(self, image: np.ndarray, camera_id: str, zone_id: Optional[str] = None) -> List[WasteDetection]:
        """检测垃圾"""
        if not self.is_loaded:
            return await self._mock_waste_detection(image, camera_id, zone_id)
        
        start_time = time.time()
        
        try:
            if not YOLO_AVAILABLE or self.model is None:
                return await self._mock_waste_detection(image, camera_id, zone_id)
            
            # 执行推理
            results = self.model(
                image,
                conf=self.config.confidence_threshold,
                iou=self.config.nms_threshold,
                max_det=self.config.max_detections,
                verbose=False
            )
            
            detections = []
            
            for result in results:
                boxes = result.boxes
                if boxes is not None:
                    for i, box in enumerate(boxes):
                        # 获取边界框坐标
                        x1, y1, x2, y2 = box.xyxy[0].cpu().numpy()
                        
                        # 获取类别和置信度
                        class_id = int(box.cls[0].cpu().numpy())
                        confidence = float(box.conf[0].cpu().numpy())
                        
                        # 获取类别名称
                        class_name = self.model.names[class_id]
                        
                        # 映射到垃圾类型
                        waste_type = self.waste_type_mapping.get(class_name, WasteType.UNKNOWN)
                        
                        # 只处理识别为垃圾的物品
                        if waste_type != WasteType.UNKNOWN or class_name in ['bottle', 'cup', 'banana', 'apple']:
                            # 计算面积
                            area = (x2 - x1) * (y2 - y1)
                            
                            # 过滤太小的检测
                            if area >= self.config.min_area_threshold:
                                detection = WasteDetection(
                                    detection_id=str(uuid4()),
                                    waste_type=waste_type,
                                    confidence=confidence,
                                    bounding_box=[float(x1), float(y1), float(x2), float(y2)],
                                    area=float(area),
                                    location=((x1 + x2) / 2, (y1 + y2) / 2),
                                    timestamp=datetime.now(),
                                    camera_id=camera_id,
                                    zone_id=zone_id
                                )
                                
                                detections.append(detection)
                                self.stats['waste_type_counts'][waste_type.value] += 1
            
            # 更新统计
            processing_time = time.time() - start_time
            self.stats['total_detections'] += 1
            self.stats['successful_detections'] += 1
            
            # 更新平均处理时间
            total_time = (self.stats['average_processing_time'] * 
                         (self.stats['successful_detections'] - 1) + processing_time)
            self.stats['average_processing_time'] = total_time / self.stats['successful_detections']
            
            return detections
            
        except Exception as e:
            self.stats['failed_detections'] += 1
            logger.error(f"Waste detection failed: {e}")
            return await self._mock_waste_detection(image, camera_id, zone_id)
    
    async def _mock_waste_detection(self, image: np.ndarray, camera_id: str, zone_id: Optional[str] = None) -> List[WasteDetection]:
        """模拟垃圾检测"""
        # 模拟延迟
        await asyncio.sleep(0.05)
        
        height, width = image.shape[:2]
        detections = []
        
        # 生成随机数量的垃圾检测结果
        num_waste = np.random.randint(0, 6)  # 0-5个垃圾
        
        waste_types = [WasteType.PLASTIC, WasteType.PAPER, WasteType.ORGANIC, WasteType.GLASS, WasteType.METAL]
        
        for i in range(num_waste):
            # 随机生成边界框
            x1 = np.random.randint(0, width - 100)
            y1 = np.random.randint(0, height - 100)
            x2 = x1 + np.random.randint(50, 150)
            y2 = y1 + np.random.randint(50, 150)
            
            # 确保边界框在图像范围内
            x2 = min(x2, width)
            y2 = min(y2, height)
            
            area = (x2 - x1) * (y2 - y1)
            
            if area >= self.config.min_area_threshold:
                waste_type = np.random.choice(waste_types)
                confidence = np.random.uniform(self.config.confidence_threshold, 1.0)
                
                detection = WasteDetection(
                    detection_id=str(uuid4()),
                    waste_type=waste_type,
                    confidence=confidence,
                    bounding_box=[float(x1), float(y1), float(x2), float(y2)],
                    area=float(area),
                    location=((x1 + x2) / 2, (y1 + y2) / 2),
                    timestamp=datetime.now(),
                    camera_id=camera_id,
                    zone_id=zone_id
                )
                
                detections.append(detection)
        
        return detections
    
    def annotate_image(self, image: np.ndarray, detections: List[WasteDetection]) -> np.ndarray:
        """在图像上标注检测结果"""
        annotated_image = image.copy()
        
        # 垃圾类型颜色映射
        color_map = {
            WasteType.PLASTIC: (0, 255, 255),    # 黄色
            WasteType.PAPER: (255, 255, 0),      # 青色
            WasteType.ORGANIC: (0, 255, 0),      # 绿色
            WasteType.GLASS: (255, 0, 255),      # 紫色
            WasteType.METAL: (128, 128, 128),    # 灰色
            WasteType.HAZARDOUS: (0, 0, 255),    # 红色
            WasteType.ELECTRONIC: (255, 0, 0),   # 蓝色
            WasteType.UNKNOWN: (255, 255, 255)   # 白色
        }
        
        for detection in detections:
            x1, y1, x2, y2 = [int(coord) for coord in detection.bounding_box]
            color = color_map.get(detection.waste_type, (255, 255, 255))
            
            # 绘制边界框
            cv2.rectangle(annotated_image, (x1, y1), (x2, y2), color, 2)
            
            # 绘制标签
            label = f"{detection.waste_type.value}: {detection.confidence:.2f}"
            label_size = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 2)[0]
            
            # 绘制标签背景
            cv2.rectangle(annotated_image, (x1, y1 - label_size[1] - 10), 
                         (x1 + label_size[0], y1), color, -1)
            
            # 绘制标签文本
            cv2.putText(annotated_image, label, (x1, y1 - 5), 
                       cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 2)
        
        return annotated_image
    
    def get_statistics(self) -> Dict[str, Any]:
        """获取统计信息"""
        return {
            'total_detections': self.stats['total_detections'],
            'successful_detections': self.stats['successful_detections'],
            'failed_detections': self.stats['failed_detections'],
            'success_rate': (self.stats['successful_detections'] / self.stats['total_detections'] 
                           if self.stats['total_detections'] > 0 else 0),
            'average_processing_time': self.stats['average_processing_time'],
            'waste_type_distribution': dict(self.stats['waste_type_counts'])
        }


class WasteTracker:
    """垃圾跟踪器"""
    
    def __init__(self, max_age: int = 30):
        self.max_age = max_age  # 最大跟踪年龄（帧数）
        self.tracks: Dict[str, Dict[str, Any]] = {}
        self.next_id = 1
    
    def update(self, detections: List[WasteDetection]) -> List[WasteDetection]:
        """更新跟踪"""
        updated_detections = []
        
        for detection in detections:
            best_match_id = None
            best_distance = float('inf')
            
            # 查找最佳匹配的跟踪
            for track_id, track in self.tracks.items():
                if track['age'] > self.max_age:
                    continue
                
                # 计算中心点距离
                distance = self._calculate_distance(
                    detection.location, track['last_location']
                )
                
                # 检查垃圾类型是否匹配
                if (distance < best_distance and distance < 100 and  # 距离阈值
                    track['waste_type'] == detection.waste_type):
                    best_distance = distance
                    best_match_id = track_id
            
            if best_match_id:
                # 更新现有跟踪
                detection.detection_id = best_match_id
                self.tracks[best_match_id]['last_location'] = detection.location
                self.tracks[best_match_id]['age'] = 0
                self.tracks[best_match_id]['confidence'] = max(
                    self.tracks[best_match_id]['confidence'], detection.confidence
                )
            else:
                # 创建新跟踪
                track_id = f"waste_track_{self.next_id:04d}"
                self.next_id += 1
                detection.detection_id = track_id
                self.tracks[track_id] = {
                    'last_location': detection.location,
                    'waste_type': detection.waste_type,
                    'confidence': detection.confidence,
                    'age': 0,
                    'first_seen': detection.timestamp
                }
            
            updated_detections.append(detection)
        
        # 增加所有跟踪的年龄
        for track in self.tracks.values():
            track['age'] += 1
        
        # 移除过期的跟踪
        expired_tracks = [
            track_id for track_id, track in self.tracks.items()
            if track['age'] > self.max_age
        ]
        for track_id in expired_tracks:
            del self.tracks[track_id]
        
        return updated_detections
    
    def _calculate_distance(self, point1: Tuple[float, float], point2: Tuple[float, float]) -> float:
        """计算两点间距离"""
        return np.sqrt((point1[0] - point2[0])**2 + (point1[1] - point2[1])**2)


class WasteDetectionService:
    """垃圾检测服务"""
    
    def __init__(self):
        self.config = WasteDetectionConfig()
        self.model = WasteDetectionModel(self.config)
        self.tracker = WasteTracker()
        
        self.analysis_results: List[WasteAnalysisResult] = []
        self.detected_issues: List[HygieneIssue] = []
        
        # 服务状态
        self._running = False
        self._monitoring_task = None
        self.monitoring_interval = 30.0  # 30秒检查一次
        
        # 统计信息
        self.service_stats = {
            'total_analyses': 0,
            'total_waste_detected': 0,
            'total_issues_generated': 0,
            'average_waste_per_analysis': 0.0
        }
    
    async def start_service(self):
        """启动服务"""
        if self._running:
            return
        
        # 加载模型
        await self.model.load_model()
        
        self._running = True
        self._monitoring_task = asyncio.create_task(self._monitoring_loop())
        logger.info("Waste detection service started")
    
    async def stop_service(self):
        """停止服务"""
        self._running = False
        if self._monitoring_task:
            self._monitoring_task.cancel()
            try:
                await self._monitoring_task
            except asyncio.CancelledError:
                pass
        logger.info("Waste detection service stopped")
    
    async def _monitoring_loop(self):
        """监控循环"""
        while self._running:
            try:
                await self._periodic_monitoring()
                await asyncio.sleep(self.monitoring_interval)
            except asyncio.CancelledError:
                break
            except Exception as e:
                logger.error(f"Error in waste detection monitoring loop: {e}")
                await asyncio.sleep(5.0)
    
    async def _periodic_monitoring(self):
        """周期性监控"""
        # 清理过期的分析结果
        cutoff_time = datetime.now() - timedelta(days=7)  # 保留7天
        self.analysis_results = [
            result for result in self.analysis_results 
            if result.timestamp > cutoff_time
        ]
        
        # 清理已解决的问题
        self.detected_issues = [
            issue for issue in self.detected_issues 
            if not issue.is_resolved or issue.detected_at > cutoff_time
        ]
        
        # 更新统计信息
        self._update_service_statistics()
    
    def _update_service_statistics(self):
        """更新服务统计"""
        if self.analysis_results:
            total_waste = sum(result.total_waste_count for result in self.analysis_results)
            self.service_stats['total_analyses'] = len(self.analysis_results)
            self.service_stats['total_waste_detected'] = total_waste
            self.service_stats['average_waste_per_analysis'] = total_waste / len(self.analysis_results)
        
        self.service_stats['total_issues_generated'] = len(self.detected_issues)
    
    async def analyze_waste(self, image: np.ndarray, camera_id: str, zone_id: Optional[str] = None) -> WasteAnalysisResult:
        """分析垃圾"""
        start_time = time.time()
        
        try:
            # 检测垃圾
            detections = await self.model.detect_waste(image, camera_id, zone_id)
            
            # 跟踪垃圾
            if self.config.enable_tracking:
                detections = self.tracker.update(detections)
            
            # 统计垃圾类型分布
            waste_type_distribution = defaultdict(int)
            total_waste_area = 0.0
            
            for detection in detections:
                waste_type_distribution[detection.waste_type.value] += 1
                total_waste_area += detection.area
            
            processing_time = time.time() - start_time
            
            # 创建分析结果
            result = WasteAnalysisResult(
                analysis_id=str(uuid4()),
                camera_id=camera_id,
                timestamp=datetime.now(),
                detections=detections,
                total_waste_count=len(detections),
                waste_type_distribution=dict(waste_type_distribution),
                total_waste_area=total_waste_area,
                processing_time=processing_time,
                model_info={
                    'model_type': self.config.model_type,
                    'confidence_threshold': self.config.confidence_threshold,
                    'version': '1.0'
                }
            )
            
            # 存储结果
            self.analysis_results.append(result)
            
            # 保持最近1000个结果
            if len(self.analysis_results) > 1000:
                self.analysis_results = self.analysis_results[-1000:]
            
            # 生成卫生问题
            await self._generate_hygiene_issues(detections, camera_id, zone_id)
            
            return result
            
        except Exception as e:
            logger.error(f"Waste analysis failed: {e}")
            raise
    
    async def _generate_hygiene_issues(self, detections: List[WasteDetection], camera_id: str, zone_id: Optional[str]):
        """生成卫生问题"""
        for detection in detections:
            # 根据垃圾类型和大小确定问题严重程度
            severity = self._determine_issue_severity(detection)
            
            # 确定问题类型
            issue_type = self._determine_issue_type(detection)
            
            # 生成问题描述
            description = self._generate_issue_description(detection)
            
            issue = HygieneIssue(
                issue_id=str(uuid4()),
                issue_type=issue_type,
                severity=severity,
                description=description,
                location=detection.location,
                bounding_box=detection.bounding_box,
                confidence=detection.confidence,
                camera_id=camera_id,
                zone_id=zone_id or "unknown",
                detected_at=detection.timestamp
            )
            
            self.detected_issues.append(issue)
        
        # 保持最近500个问题
        if len(self.detected_issues) > 500:
            self.detected_issues = self.detected_issues[-500:]
    
    def _determine_issue_severity(self, detection: WasteDetection) -> str:
        """确定问题严重程度"""
        if detection.waste_type == WasteType.HAZARDOUS:
            return "critical"
        elif detection.area > 10000:  # 大面积垃圾
            return "high"
        elif detection.area > 5000:
            return "medium"
        else:
            return "low"
    
    def _determine_issue_type(self, detection: WasteDetection) -> HygieneIssueType:
        """确定问题类型"""
        if detection.waste_type == WasteType.HAZARDOUS:
            return HygieneIssueType.DAMAGE
        else:
            return HygieneIssueType.LITTER
    
    def _generate_issue_description(self, detection: WasteDetection) -> str:
        """生成问题描述"""
        waste_type_names = {
            WasteType.PLASTIC: "塑料垃圾",
            WasteType.PAPER: "纸类垃圾",
            WasteType.ORGANIC: "有机垃圾",
            WasteType.GLASS: "玻璃垃圾",
            WasteType.METAL: "金属垃圾",
            WasteType.HAZARDOUS: "有害垃圾",
            WasteType.ELECTRONIC: "电子垃圾",
            WasteType.UNKNOWN: "未知垃圾"
        }
        
        waste_name = waste_type_names.get(detection.waste_type, "垃圾")
        
        if detection.area > 10000:
            return f"检测到大面积{waste_name}，需要立即清理"
        elif detection.area > 5000:
            return f"检测到{waste_name}，建议及时清理"
        else:
            return f"检测到{waste_name}"
    
    def annotate_image(self, image: np.ndarray, result: WasteAnalysisResult) -> np.ndarray:
        """在图像上标注分析结果"""
        return self.model.annotate_image(image, result.detections)
    
    async def get_analysis_results(
        self,
        camera_id: Optional[str] = None,
        zone_id: Optional[str] = None,
        waste_type: Optional[WasteType] = None,
        start_time: Optional[datetime] = None,
        end_time: Optional[datetime] = None,
        limit: int = 100
    ) -> List[WasteAnalysisResult]:
        """获取分析结果"""
        results = self.analysis_results
        
        # 过滤条件
        if camera_id:
            results = [r for r in results if r.camera_id == camera_id]
        
        if start_time:
            results = [r for r in results if r.timestamp >= start_time]
        
        if end_time:
            results = [r for r in results if r.timestamp <= end_time]
        
        if waste_type:
            results = [
                r for r in results 
                if any(d.waste_type == waste_type for d in r.detections)
            ]
        
        if zone_id:
            results = [
                r for r in results 
                if any(d.zone_id == zone_id for d in r.detections)
            ]
        
        # 按时间倒序排列
        results.sort(key=lambda x: x.timestamp, reverse=True)
        
        return results[:limit]
    
    async def get_hygiene_issues(
        self,
        camera_id: Optional[str] = None,
        zone_id: Optional[str] = None,
        issue_type: Optional[HygieneIssueType] = None,
        is_resolved: Optional[bool] = None,
        limit: int = 100
    ) -> List[HygieneIssue]:
        """获取卫生问题"""
        issues = self.detected_issues
        
        # 过滤条件
        if camera_id:
            issues = [i for i in issues if i.camera_id == camera_id]
        
        if zone_id:
            issues = [i for i in issues if i.zone_id == zone_id]
        
        if issue_type:
            issues = [i for i in issues if i.issue_type == issue_type]
        
        if is_resolved is not None:
            issues = [i for i in issues if i.is_resolved == is_resolved]
        
        # 按检测时间倒序排列
        issues.sort(key=lambda x: x.detected_at, reverse=True)
        
        return issues[:limit]
    
    async def resolve_issue(self, issue_id: str, resolution_notes: str = "") -> bool:
        """解决卫生问题"""
        for issue in self.detected_issues:
            if issue.issue_id == issue_id:
                issue.is_resolved = True
                issue.resolved_at = datetime.now()
                issue.resolution_notes = resolution_notes
                logger.info(f"Hygiene issue resolved: {issue_id}")
                return True
        
        return False
    
    def get_waste_statistics(self, time_range: timedelta = timedelta(hours=24)) -> Dict[str, Any]:
        """获取垃圾统计"""
        end_time = datetime.now()
        start_time = end_time - time_range
        
        # 获取时间范围内的结果
        recent_results = [
            result for result in self.analysis_results
            if start_time <= result.timestamp <= end_time
        ]
        
        if not recent_results:
            return {
                'time_range': {
                    'start': start_time.isoformat(),
                    'end': end_time.isoformat()
                },
                'total_analyses': 0,
                'statistics': {}
            }
        
        # 统计垃圾类型分布
        total_waste_distribution = defaultdict(int)
        total_waste_count = 0
        total_waste_area = 0.0
        
        for result in recent_results:
            total_waste_count += result.total_waste_count
            total_waste_area += result.total_waste_area
            
            for waste_type, count in result.waste_type_distribution.items():
                total_waste_distribution[waste_type] += count
        
        # 计算平均值
        avg_waste_per_analysis = total_waste_count / len(recent_results)
        avg_area_per_analysis = total_waste_area / len(recent_results)
        
        return {
            'time_range': {
                'start': start_time.isoformat(),
                'end': end_time.isoformat()
            },
            'total_analyses': len(recent_results),
            'statistics': {
                'total_waste_count': total_waste_count,
                'total_waste_area': total_waste_area,
                'average_waste_per_analysis': avg_waste_per_analysis,
                'average_area_per_analysis': avg_area_per_analysis,
                'waste_type_distribution': dict(total_waste_distribution),
                'most_common_waste_type': max(total_waste_distribution.items(), key=lambda x: x[1])[0] if total_waste_distribution else None
            },
            'model_statistics': self.model.get_statistics(),
            'service_statistics': self.service_stats
        }
    
    def update_config(self, config: WasteDetectionConfig):
        """更新配置"""
        self.config = config
        self.model.config = config
        logger.info("Waste detection configuration updated")
    
    def get_config(self) -> WasteDetectionConfig:
        """获取配置"""
        return self.config
    
    # 模型管理接口
    async def create_training_dataset(self, samples: List[Dict[str, Any]]) -> Dict[str, Any]:
        """创建训练数据集"""
        return await waste_model_manager.create_training_dataset(samples)
    
    async def train_custom_model(self, training_config: Dict[str, Any] = None) -> Dict[str, Any]:
        """训练自定义模型"""
        return await waste_model_manager.train_waste_detection_model(training_config)
    
    async def validate_model_accuracy(self, model_path: str = None, confidence_threshold: float = 0.5) -> Dict[str, Any]:
        """验证模型精度"""
        return await waste_model_manager.validate_model_accuracy(model_path, confidence_threshold)
    
    async def load_custom_model(self, model_path: str):
        """加载自定义模型"""
        try:
            # 更新模型管理器中的模型
            waste_model_manager.trainer.load_model(model_path)
            
            # 更新检测服务中的模型
            if waste_model_manager.trainer.current_model:
                self.model.model = waste_model_manager.trainer.current_model
                logger.info(f"Custom model loaded: {model_path}")
            else:
                logger.warning(f"Failed to load custom model: {model_path}")
        except Exception as e:
            logger.error(f"Error loading custom model: {e}")
            raise
    
    async def get_model_report(self) -> Dict[str, Any]:
        """获取模型报告"""
        return await waste_model_manager.generate_model_report()
    
    def get_model_statistics(self) -> Dict[str, Any]:
        """获取模型统计信息"""
        return waste_model_manager.get_model_statistics()
    
    async def add_training_sample(self, image: np.ndarray, detections: List[WasteDetection], image_id: str = None) -> str:
        """添加训练样本"""
        # 转换检测结果为标注格式
        annotations = []
        for detection in detections:
            annotations.append({
                'waste_type': detection.waste_type.value,
                'bounding_box': detection.bounding_box,
                'confidence': detection.confidence
            })
        
        # 添加到数据集
        sample = {
            'image': image,
            'annotations': annotations,
            'image_id': image_id
        }
        
        return waste_model_manager.dataset.add_sample(image, annotations, image_id)
    
    async def export_training_data(self, output_path: str) -> Dict[str, Any]:
        """导出训练数据"""
        try:
            import shutil
            from pathlib import Path
            
            output_dir = Path(output_path)
            output_dir.mkdir(parents=True, exist_ok=True)
            
            # 复制数据集
            dataset_source = waste_model_manager.dataset.dataset_path
            dataset_target = output_dir / "dataset"
            
            if dataset_source.exists():
                shutil.copytree(dataset_source, dataset_target, dirs_exist_ok=True)
            
            # 导出统计信息
            stats = waste_model_manager.dataset.get_statistics()
            stats_file = output_dir / "dataset_stats.json"
            
            with open(stats_file, 'w', encoding='utf-8') as f:
                json.dump(stats, f, ensure_ascii=False, indent=2)
            
            export_info = {
                'export_path': str(output_dir),
                'dataset_stats': stats,
                'exported_at': datetime.now().isoformat()
            }
            
            logger.info(f"Training data exported to: {output_path}")
            return export_info
            
        except Exception as e:
            logger.error(f"Failed to export training data: {e}")
            raise
    
    async def process_video_frame(self, frame: np.ndarray, metadata: Dict[str, Any] = None) -> Dict[str, Any]:
        """处理视频帧进行垃圾检测"""
        try:
            camera_id = metadata.get('camera_id', 'unknown') if metadata else 'unknown'
            zone_id = metadata.get('zone_id') if metadata else None
            frame_timestamp = datetime.fromisoformat(metadata.get('frame_timestamp')) if metadata and metadata.get('frame_timestamp') else datetime.now()
            
            # 进行垃圾分析
            analysis_result = await self.analyze_waste(frame, camera_id, zone_id)
            
            # 获取最近的卫生问题
            recent_issues = await self.get_hygiene_issues(
                camera_id=camera_id,
                zone_id=zone_id,
                is_resolved=False,
                limit=5
            )
            
            return {
                "algorithm": "waste_detection",
                "camera_id": camera_id,
                "frame_timestamp": frame_timestamp.isoformat(),
                "processing_timestamp": datetime.now().isoformat(),
                "results": {
                    "total_waste_count": analysis_result.total_waste_count,
                    "total_waste_area": analysis_result.total_waste_area,
                    "waste_type_distribution": analysis_result.waste_type_distribution,
                    "detections": [
                        {
                            "detection_id": d.detection_id,
                            "waste_type": d.waste_type.value,
                            "confidence": d.confidence,
                            "bounding_box": d.bounding_box,
                            "area": d.area,
                            "location": d.location
                        } for d in analysis_result.detections
                    ],
                    "hygiene_issues": [
                        {
                            "issue_id": issue.issue_id,
                            "issue_type": issue.issue_type.value,
                            "severity": issue.severity,
                            "description": issue.description,
                            "confidence": issue.confidence
                        } for issue in recent_issues
                    ]
                },
                "confidence": 0.82,
                "processing_time": analysis_result.processing_time
            }
            
        except Exception as e:
            logger.error(f"垃圾检测处理视频帧失败: {e}")
            return {
                "algorithm": "waste_detection",
                "camera_id": metadata.get('camera_id', 'unknown') if metadata else 'unknown',
                "error": str(e),
                "processing_timestamp": datetime.now().isoformat()
            }


# 全局垃圾检测服务实例
waste_detection_service = WasteDetectionService()